home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
bytjl86b.arc
/
UGHBUG.ASM
< prev
Wrap
Assembly Source File
|
1985-07-12
|
32KB
|
1,567 lines
TITLE ' UGHBUG VERSION 1.00 12 January 1986 '
SBTTL ' Copyright 1986 by George Dinwiddie '
PGLEN 55
;
; NOTICE : This monitor program may be copied and distributed on the
; condition that all copyright notices and this notice remain intact.
; This program is provided without any warranty or assumption of
; liability whatsoever. If it doesn't work or it breaks something, I'm
; sorry, but it's not my problem.
;
; On the positive side, if this program helps you, I am glad to be of
; assistance. I ask only two favors. First, if you fix any bugs or
; add any enhancements, please send me a copy. (CP/M 8" SSSD or IBM-PC
; 5.25" are best for me.) Secondly, if you use this program to help
; develop a commercial product, please remember me. As a suggestion, a
; $50.00 donation would be a bargain for you and welcome by me. If you
; would prefer, either a sample of your product or a donation more in
; line with the profits on your product would be ok, too. If you use
; this program on a home project, I understand that you can't alway
; afford to pay for the value of good software. My own CP/M computer
; would be worthless without the wonderful public domain software that
; I have received for free. If you want to send me your favorite
; public domain goody, great. In any event, you are welcome to this --
; enjoy, enjoy.
;
; George Dinwiddie
; 10965 Trotting Ridge Way
; Columbia, MD 21044
;
;REVISION HISTORY :
;
;Version 1.00 George Dinwiddie 12 January 1986.
; First public release. Fixed GO-from-break bug.
;Version 0.16 George Dinwiddie 26 January 1984
; Added JUMPTABLE and HEXMATH functions.
;
;WISH LIST :
;
; Load command ('L') to load ram from a hex file through the terminal
; port.
;
; Find command ('F') to search for sequences specified in hex or
; ascii. I always intended to add this one but never did. That's
; the reason the Insert command isn't a Fill command.
;
; Disassemble command (maybe 'U' for Unassemble).
;
; Single-line assembler. It's amazing how good you get at hand
; assembly when you practice. Still, it would be nice to have this.
;
;
;NOTE : Some labels are of the following form :
; IF000 == IF
; THN000 == THEN
; ELS000 == ELSE
; NDI000 == ENDIF
;
MONBASE EQU 0000H ;4K MONITOR
APPBASE EQU 2000H ;8K APPLICATION EPROM
RAMBASE EQU 4000H ;8K RAM
UARTBASE EQU 7800H ;TERMINAL (uart) LOCATION
UARTDATA EQU UARTBASE ; C/D* = A0
UARTCONT EQU (UARTBASE+1)
RAMEND EQU 5FFFH ;END OF EXTERNAL RAMSPACE
BYTENUM EQU (RAMEND-8) ;FROM HERE ON USED BY BREAK ROUTINE
STACK EQU 50H ;stack begins here
PCON EQU 87H ;AVOCET ASSEMBLER DOESN'T KNOW PCON
;reserved internal ram locations
RESERVED EQU 48H ;reserved internal ram
HIBYTE EQU RESERVED ;TOP OF 16-BIT ADDRESS
LOBYTE EQU RESERVED+1 ;BOTTOM OF 16 BIT ADDRESS
FIRST EQU RESERVED+2 ;START ADDRESS HIGH (LOW IN RESERVED+3)
LAST EQU RESERVED+4 ;END ADDRESS HIGH (LOW IN RESERVED+5)
TO EQU RESERVED+6 ;TO ADDRESS HIGH (LOW IN RESERVED+7)
;reserved register bank (and aliases for those registers)
RESBANK EQU 1 ;register bank 1
REG0 EQU 8*RESBANK
REG1 EQU REG0+1 ;sometimes you can't use R1
REG2 EQU REG0+2
REG3 EQU REG0+3
REG4 EQU REG0+4
REG5 EQU REG0+5
REG6 EQU REG0+6
REG7 EQU REG0+7
;character equates
CR EQU 0DH ;CARRIAGE RETURN
LF EQU 0AH ;LINE FEED
SPACE EQU 20H ;SPACE CHARACTER
TAB EQU 09H ;TAB CHARACTER
DOT EQU 2EH ;PERIOD
BACKSP EQU 08H ;BACKSPACE
EOT EQU 04H ;end of text
;***********************************************************
ORG MONBASE
START: JMP UGHBUG
ORG START+03H
LJMP RAMBASE+03H ;INTERRUPT VECTORS JUMP TO RAM
ORG START+0BH
LJMP RAMBASE+0BH
ORG START+13H
LJMP RAMBASE+13H
ORG START+1BH
LJMP RAMBASE+1BH
ORG START+23H
LJMP RAMBASE+23H
;*************************************************************
LJMPTBL: LJMP COOL
LJMP WARM
LJMP IN
LJMP INCH
LJMP INHEX
LJMP BYTES
LJMP BADDR
LJMP THRADR
LJMP OUT
LJMP OUTCH
LJMP OUTS
LJMP OUT2S
LJMP CRLF
LJMP OUT2H
LJMP OUTR0
LJMP OUTC2HS
LJMP PDATA
LJMP INC16
LJMP DEC16
LJMP CPY
LJMP BRKPT
PAGE
MSIGNON:
DB CR, LF, 'Ughbug MCS-51 monitor, version 1.00'
DB CR, LF, 'copyright 1986 by George Dinwiddie.', LF, 04H
;*************************************************************
UGHBUG: MOV SP,#STACK
MOV STACK,SP ;store stack pointer for cool start
SETB RS0 ;SELECT REGISTER BANK 1
CLR RS1
CLR A
MOV DPTR,#BYTENUM
MOV R0,#(RAMEND-BYTENUM+1)
CLEAR: MOVX @DPTR,A ;clear space used by break routine
INC DPTR
DJNZ R0,CLEAR
DLAY: DJNZ ACC,DLAY ;WAIT HERE FOR UART TO WAKE-UP
DJNZ R0,DLAY
MOV DPTR,#UARTCONT ;INIT UART
CLR A
MOVX @DPTR,A ;send three zeros because you don't know
NOP ;in what crazy mode the ugh-art wakes up
DJNZ ACC,$-1
MOVX @DPTR,A
NOP
DJNZ ACC,$-1
MOVX @DPTR,A
NOP
DJNZ ACC,$-1
MOV A,#40H ;software reset uart
MOVX @DPTR,A
CLR A ;many thanks to Ernest Penzenstadler
NOP ;for taming the infamous 8251A ugh-art!
DJNZ ACC,$-1
MOV A,#01001110B ;MODE
MOVX @DPTR,A
MOVX A,@DPTR ;GET STATUS
JNB ACC.0,$-1 ;WAIT FOR TXRDY
MOV A,#00110111B ;COMMAND
MOVX @DPTR,A
MOV DPTR,#MSIGNON
CALL PDATA
COOL: MOV SP,STACK
;*************************************************************
WARM:
MOV DPTR,#MPROMPT ;WARM START
CALL PDATA
CALL INCH
JNB ACC.6,$+5 ;JUMP IF NOT A LETTER
CLR ACC.5 ;CONVERT LOWER TO UPPER CASE
MOV R7,A ;SAVE CHARACTER INPUT
MOV DPTR,#FUNTAB ;POINT TO FUNCTION TABLE
SCAN: CLR A
MOVC A,@A+DPTR
JZ WARM ;END OF TABLE
CJNE A,0FH,NEXT ;COMPARE WITH SAVED CHARACTER
MOV A,#01H
MOVC A,@A+DPTR ;GET HIGH BYTE OF JUMP
MOV R2,A ;SAVE IN R2
MOV A,#02H
MOVC A,@A+DPTR ;GET LOW BYTE OF JUMP
MOV R3,A ;SAVE IN R3
PUSH REG3 ;PUSH R3 (LOW BYTE)
PUSH REG2 ;PUSH R2 (HIGH BYTE)
RET ;POP & JUMP
NEXT: INC DPTR
INC DPTR
INC DPTR
JMP SCAN
PAGE
;*************************************************************
HELP:
MOV DPTR,#MHELP
CALL PDATA
JMP WARM
;*************************************************************
DUMP: CALL BADDR
JNC DMP3
CLR ACC.5 ;CONVERT LOWER TO UPPER CASE
CJNE A,#'I',DMP1
JMP DUMPI ;DUMP INTERNAL RAM
DMP1: JMP WARM
DMP3: MOV FIRST,HIBYTE ;DUMP PROGRAM MEMORY
MOV (FIRST+1),LOBYTE
MOV LAST,#0FFH
MOV (LAST+1),#0FFH
CJNE A,#CR,DMP4 ;DEFAULT IF NO END ADDRESS ENTERED
JMP (NEWLIN-6)
DMP4: CALL BADDR2
JB F0,DMP5 ;CARRIAGE RETURN READ
MOV LAST,HIBYTE
MOV (LAST+1),LOBYTE
DMP5: MOV DPTR,#MINDEX
LCALL PDATA
NEWLIN:
MOV DPH,FIRST
MOV DPL,(FIRST+1)
ANL DPL,#0F0H
CALL CRLF
MOV R0,DPH
CALL OUTR0 ;DISPLAY ADDRESS
MOV R0,DPL
CALL OUTR0
CALL OUT2S
SPACES: MOV A,(FIRST+1) ;BLANK LOCATIONS BEFORE FIRST
XRL A,DPL
JZ MORE ;JUMP IF EQUAL
CALL OUT3S
INC DPTR
CALL MIDCHK
JMP SPACES
MORE: CALL OUTC2HS
MOV A,LAST
CJNE A,DPH,MOREC
MOV A,(LAST+1)
CJNE A,DPL,MOREC
JMP ENDHEX
MOREC: INC DPTR
CALL MIDCHK
JZ DASCII ;NOW DUMP ASCII
JMP MORE
ENDHEX: INC DPTR
CALL MIDCHK
JZ DASCII ;NOW DUMP ASCII (LAST LINE)
CALL OUT3S
JMP ENDHEX
DASCII: CALL OUT4S ;SHOW ASCII EQUIVALENT
MOV DPH,FIRST
MOV DPL,(FIRST+1)
ANL DPL,#0F0H
DASCI1: MOV A,(FIRST+1)
XRL A,DPL
JZ DASCI2
CALL OUTS
INC DPTR
CALL MIDCHK
JMP DASCI1
DASCI2: CLR A
MOVC A,@A+DPTR
MOV B,A
CLR C
SUBB A,#SPACE
JC BAD3
SUBB A,#(7FH-SPACE)
JC OK3
BAD3: MOV B,#DOT
OK3: MOV A,B
CALL OUTCH
MOV A,LAST
CJNE A,DPH,DASCI3
MOV A,(LAST+1)
CJNE A,DPL,DASCI3
JMP WARM
DASCI3: INC DPTR
CALL MIDCHK
JNZ DASCI2
MOV A,#16
ADD A,(FIRST+1)
ANL A,#0F0H
JNC $+4
INC FIRST
MOV (FIRST+1),A
JMP NEWLIN
;*************************************************************
TABENT EQU 11 ;LENGTH OF SFR TABLE ENTRY
OFF1 EQU 6 ;OFFSET TO HEX ADDRESS
OFF2 EQU 5 ;OFFSET TO FETCH CONTENTS
OFF3 EQU 8 ;OFFSET TO CHANGE CONTENTS
DUMPI:
CALL BADDR
JNC $+5
LJMP WARM
MOV FIRST,LOBYTE
MOV LAST,#0FFH
XRL A,#CR
JZ (LINE-6)
CALL BADDR2
JB F0,$+6 ;CARRIAGE RETURN READ
MOV LAST,LOBYTE
MOV A,#7FH ;TOP OF RAM
CLR C
SUBB A,FIRST
JC DSFR ;DONE RAM--DO SFR'S
MOV DPTR,#MINDEX
LCALL PDATA
LINE: CALL CRLF
MOV A,#7FH ;TOP OF RAM
CLR C
SUBB A,FIRST
JC DSFR ;DONE RAM--DO SFR'S
MOV R0,FIRST
ANL REG0,#0F0H ;8=R0
CALL OUTR03S ;DISPLAY ADDRESS
SPICES: MOV A,FIRST ;SPACES BEFORE BEGINNING
XRL A,R0
JZ NXTBYT
CALL OUT3S
INC R0
MOV A,#07H
ANL A,R0
JNZ $+5
LCALL OUTS ;MIDDLE OF LINE
JMP SPICES
NXTBYT: CALL OUT2H
CALL OUTS
MOV A,R0
XRL A,LAST
JNZ $+5
LJMP WARM
INC R0
MOV A,#07H
ANL A,R0
JNZ $+5
LCALL OUTS ;MIDDLE OF LINE
MOV A,#0FH
ANL A,R0
JNZ NXTBYT ;NOT END OF LINE
MOV A,FIRST
ANL A,#0F0H
ADD A,#10H
MOV FIRST,A
JMP LINE
DSFR: MOV DPTR,#(SFRTAB-TABENT)
MOV R1,#6
CALL CRLF
DSFR1: MOV A,#TABENT
ADD A,DPL
MOV DPL,A
JNC $+4
INC DPH
MOV A,#OFF1 ;OFFSET TO SFR HEX LOCATION
MOVC A,@A+DPTR
CLR C
SUBB A,FIRST
JC DSFR1 ;NOT TO FIRST YET
DSFR5: MOV A,#OFF1
MOVC A,@A+DPTR ;GET HEX LOCATION OF SFR
MOV R0,FIRST
XRL A,R0
JZ DSFR10
INC FIRST ;WASN'T A VALID SFR
MOV A,FIRST
JZ (LINE-6) ;BACK TO RAM
CJNE A,LAST,DSFR5
JMP WARM ;DONE
DSFR10: CALL OUTR0
MOV A,#('=')
CALL OUTCH
CALL PDATA ;OUTPUT LOCATION LABEL (ALTERS DPTR)
MOV A,#(':')
CALL OUTCH
MOV A,#LOW(DSFR20)
PUSH ACC
MOV A,#HIGH(DSFR20)
PUSH ACC
MOV A,#(OFF2-4) ;OFFSET TO "MOV R0,SFR"
JMP @A+DPTR
DSFR20: CALL OUTR0
CALL OUT2S
DJNZ R1,DSFR30
MOV R1,#6
CALL CRLF
DSFR30: INC FIRST
MOV A,#(TABENT-4)
ADD A,DPL
MOV DPL,A
JNC $+4
INC DPH
MOV A,FIRST
JNZ $+5
LJMP LINE
DEC A
XRL A,LAST
JNZ DSFR5
JMP WARM
;*************************************************************
COPY: CALL THRADR
CALL CPY
JMP WARM
;*************************************************************
VERIFY: CALL THRADR
VER10: MOV DPH,FIRST
MOV DPL,(FIRST+1)
CLR A
MOVC A,@A+DPTR
MOV R1,A
MOV DPH,TO
MOV DPL,(TO+1)
CLR A
MOVC A,@A+DPTR
MOV R2,A
XRL A,R1
JZ VER20 ;JUMP IF EQUAL
CALL CRLF
MOV R0,#FIRST
CALL OUT2H
MOV R0,#(FIRST+1)
CALL OUT2H
CALL OUT2S
MOV R0,#REG1 ;R1
CALL OUT2H
CALL OUT4S
MOV R0,#TO
CALL OUT2H
MOV R0,#(TO+1)
CALL OUT2H
CALL OUT2S
MOV R0,#REG2 ;R2
CALL OUT2H
VER20: MOV A,FIRST
CJNE A,LAST,VER30
MOV A,(FIRST+1)
CJNE A,(LAST+1),VER30
JMP WARM
VER30: MOV R0,#(FIRST+1)
CALL INC16
MOV R0,#(TO+1)
CALL INC16
JMP VER10
;*************************************************************
ALTER: CALL BADDR
JNC ALT05
JNB F0,ALTEND ;ERROR
CLR ACC.5 ;CONVERT LOWER TO UPPER CASE
CJNE A,#('I'),ALTEND ;ERROR
JMP SUBSTUT
ALT05: MOV FIRST,HIBYTE
MOV (FIRST+1),LOBYTE
ALT10: CALL CRLF
MOV R0,#FIRST ;SHOW ADDRESS
CALL OUT2H
INC R0
CALL OUT2H
ALT15: CALL OUTS
MOV DPH,FIRST
MOV DPL,(FIRST+1)
CLR A
MOVC A,@A+DPTR ;GET DATA
MOV R1,A
MOV R0,#REG1 ;SHOW DATA
CALL OUT2H
MOV A,#('-')
CALL OUTCH
CALL BYTES
JNC ALT20
XRL A,#BACKSP
JZ BACKUP
XRL A,#BACKSP ;RESTORE A
XRL A,#DOT
JZ BACKUP
ALTEND: JMP WARM ;ERROR
ALT20: JB F0,ALT30 ;<CR> OR SPACE
MOV A,LOBYTE
MOVX @DPTR,A ;CHANGE DATA
ALT30: MOV R0,#(FIRST+1)
CALL INC16
MOV A,B
XRL A,#CR
JZ ALT10
MOV A,(FIRST+1)
ANL A,#07H
JZ ALT10
JMP ALT15
BACKUP: MOV R0,#(FIRST+1)
CALL DEC16
JMP ALT10
;*************************************************************
MODIFY CALL BADDR
MOV DPH,HIBYTE
MOV DPL,LOBYTE
MOD10: CALL INCH
CJNE A,#BACKSP,NOTBS
DEC DPL
MOV A,#0FFH
CJNE A,DPL,MOD10
DEC DPH
JMP MOD10
NOTBS: CJNE A,#EOT,$+6
LJMP WARM
MOVX @DPTR,A
INC DPTR
JMP MOD10
;*************************************************************
SUBSTUT:
CALL BADDR
MOV R0,LOBYTE
IF010: MOV A,#7FH ;IF ADDRESS >= 80H OR <= F0H
CLR C
SUBB A,R0
JNC ELS010
MOV A,#0F0H
CLR C
SUBB A,R0
JC ELS010
THN010: MOV DPTR,#(SFRTAB-TABENT)
SUB60: MOV A,#TABENT ;INCREMENT TABLE POINTER
ADD A,DPL
MOV DPL,A
JNC $+4
INC DPH
MOV A,#OFF1 ;FIND 1ST ENTRY >= R0
MOVC A,@A+DPTR
CLR C
SUBB A,R0
JC SUB60 ;NOT FOUND YET
SUB65: MOV A,#OFF1 ;INCREMENT R0 TO LINE IN TABLE
MOVC A,@A+DPTR
XRL A,R0
JZ SUB70 ;FOUND IT
INC R0
JMP SUB65
ELS010: JMP LS010 ;RELAY STATION
SUB70: CALL CRLF ;DISPLAY ADDRESS
CALL OUTR03S
CALL PDATA ;ALTERS DPTR (ADDS 4)
MOV A,#(':')
CALL OUTCH
MOV REG1,R0 ;MOV R1,R0
MOV A,#LOW(SUB80)
PUSH ACC
MOV A,#HIGH(SUB80)
PUSH ACC
MOV A,#(OFF2-4)
JMP @A+DPTR ;CRASHES R0
SUB80: CALL OUTR0 ;DISPLAY DATA
MOV A,#('-')
CALL OUTCH
MOV R0,REG1 ;RESTORE R0
CALL BYTES
IF020: JNC ELS020 ;IF CHARACTER = DOT OR BACKSPACE
MOV A,B
XRL A,#BACKSP
JZ THN020
MOV A,B
XRL A,#DOT
JZ THN020
JMP WARM ;ERROR
THN020: ;THEN BACKUP
IF030: CJNE R0,#80H,ELS030
THN030: MOV R0,#7FH
JMP IF010
ELS030: MOV A,DPL
CLR C
SUBB A,#(TABENT+4)
MOV DPL,A
JNC $+4
DEC DPH
MOV A,#(OFF1)
MOVC A,@A+DPTR
MOV R0,A
JMP IF010
ELS020:
JB F0,SUB90
SETB F0
MOV R0,LOBYTE
MOV A,#LOW(SUB90)
PUSH ACC
MOV A,#HIGH(SUB90)
PUSH ACC
MOV A,#(OFF3-4)
JMP @A+DPTR ;CRASHES R0
SUB90: MOV R0,REG1 ;RESTORE R0
IF035: JB F0,NDI035
THN035: MOV DPTR,#MNONO
CALL PDATA
NDI035:
IF040: CJNE R0,#0F0H,NDI040 ;IF R0 = 0F
THN040: MOV R0,#0FFH ;THEN R0 = FFH
NDI040:
INC R0
JMP IF010
LS010: CALL CRLF
CALL OUTR03S
SUB20: CALL OUT2H
MOV A,#('-')
CALL OUTCH
MOV REG1,R0
CALL BYTES ;clobbers r0
MOV R0,REG1
IF050: JNC ELS050 ;IF CHAR. = BACKSP. OR DOT
MOV A,B
XRL A,#BACKSP
JZ THN050
MOV A,B
XRL A,#DOT
JZ THN050
JMP WARM
THN050: ;THEN BACKUP
IF060: MOV A,R0
JNZ NDI060 ;IF R0 = 0
THN060: MOV R0,#0F1H ;THEN R0 = F1H
NDI060:
NDI050:
DEC R0
F010: JMP IF010 ;ALSO USED FOR RELAY
ELS050:
IF070: JB F0,NDI070 ;IF NOT SPACE OR CR
THN070: MOV A,LOBYTE ;THEN CHANGE BYTE
MOV @R0,A
NDI070: INC R0
MOV A,#07H
ANL A,R0
JZ F010
CALL OUT2S
JMP SUB20
;*************************************************************
INSERT: CALL THRADR
MOV DPH,FIRST
MOV DPL,(FIRST+1)
INS10: MOV A,(TO+1)
MOVX @DPTR,A
MOV A,DPH
CJNE A,LAST,INS20
MOV A,DPL
CJNE A,(LAST+1),INS20
JMP WARM
INS20: INC DPTR
JMP INS10
;*************************************************************
BREAK: ; REMOVE OLD BREAKPOINT
MOV DPTR,#BYTENUM
CLR A
MOVC A,@A+DPTR
MOV R1,A ;SAVE OLD BYTENUM IN R1
IF100: JZ NDI100 ;IF THERE IS AN OLD BREAKPOINT
THN100: MOV FIRST,#HIGH(BYTENUM+1) ;THEN REMOVE IT
MOV FIRST+1,#LOW(BYTENUM+1)
MOV LAST,#HIGH(BYTENUM)
MOV A,#LOW(BYTENUM)
ADD A,R1 ;ADD OLD BYTENUM
MOV LAST+1,A
JNC $+4
INC LAST
MOV DPTR,#(RAMEND-1)
CLR A
MOVC A,@A+DPTR
MOV TO,A
MOV DPTR,#RAMEND
CLR A
MOVC A,@A+DPTR
CLR C
SUBB A,R1 ;SUBTRACT OLD BYTENUM
MOV TO+1,A
JNC $+4
DEC T0
CALL CPY
CLR A ;CLEAR END OF RAM
MOV DPTR,#BYTENUM
MOV R0,#(RAMEND-BYTENUM+1-3) ;LEAVE JUMP INSTRUCTION
CLEAR1: MOVX @DPTR,A
INC DPTR
DJNZ R0,CLEAR1
NDI100:
CALL BYTES ;INSTALL NEW BREAKPOINT
IF150: JNC NDI150 ;IF NOT VALID HEX
JMP WARM ;THEN END
NDI150:
IF155: JNB F0,NDI155 ;IF CR
XRL A,#SPACE
JZ NDI100 ;AND NOT SPACE
JMP WARM ;THEN END
NDI155: MOV FIRST,HIBYTE
MOV FIRST+1,LOBYTE
MOV DPTR,#BYTENUM
MOV A,#3 ;IN CASE OF DEFAULT
MOVX @DPTR,A
MOV R1,A ;SAVE DEFAULT NEW BYTENUM
IF160: MOV A,B
XRL A,#CR
JZ NDI160
THN160: CALL INHEX ;get BYTENUM
IF170: JNC ELS170 ;if not valid hex
THN170: MOV A,B ;then check for space or CR
XRL A,#SPACE
JZ THN160
MOV A,B
XRL A,#CR
JZ NDI170
MOV DPTR,#BYTENUM
CLR A
MOVX @DPTR,A
JMP WARM
ELS170: MOV DPTR,#BYTENUM ;else accept only 3, 4 or 5
MOVX @DPTR,A
MOV R1,A ;SAVE NEW BYTENUM
SUBB A,#3
JC BAD4
SUBB A,#(6-3)
JNC BAD4
JMP NDI170
BAD4: MOV DPTR,#BYTENUM
CLR A
MOVX @DPTR,A
JMP WARM
NDI170:
NDI160:
;FIRST,FIRST+1 AND HIBYTE,LOBYTE
; BOTH CONTAIN BREAK ADDRESS
;R1 CONTAINS NEW BYTENUM
MOV DPTR,#(RAMEND-2)
MOV A,#02H ;"LJMP"
MOVX @DPTR,A
MOV A,FIRST+1
ADD A,R1 ;ADD BYTENUM
MOV LAST+1,A
MOV DPTR,#RAMEND
MOVX @DPTR,A
MOV A,FIRST
JNC $+3
INC A
MOV LAST,A
MOV DPTR,#(RAMEND-1)
MOVX @DPTR,A
MOV R0,#(LAST+1)
CALL DEC16 ;ADJUST (LAST,LAST+1)
MOV TO,#HIGH(BYTENUM+1)
MOV TO+1,#LOW(BYTENUM+1)
CALL CPY ;SAVE INSTRUCTIONS IN END OF RAM
MOV DPL,LOBYTE
MOV DPH,HIBYTE ;INSERT JUMP TO BRKPT
MOV A,#02H ;"LJMP"
MOVX @DPTR,A
INC DPTR
MOV A,#HIGH(BRKPT)
MOVX @DPTR,A
INC DPTR
MOV A,#LOW(BRKPT)
MOVX @DPTR,A
JMP WARM
;*************************************************************
BRKPT: PUSH ACC
PUSH PSW
PUSH B
PUSH DPH
PUSH DPL
MOV STACK,SP ;save current stack level for cool start
SETB RS0 ;SELECT REGISTER BANK 1
CLR RS1
MOV DPTR,#MBRK1
CALL PDATA
MOV DPTR,#(BYTENUM)
CLR A
MOVC A,@A+DPTR
MOV R0,A
MOV DPTR,#(RAMEND)
CLR A
MOVC A,@A+DPTR
CLR C
SUBB A,R0
MOV B,A
MOV DPTR,#(RAMEND-1)
CLR A
MOVC A,@A+DPTR
MOV R0,A
JNC $+3
DEC R0
CALL OUTR0
MOV R0,B
CALL OUTR0
MOV DPTR,#MBRK2
CALL PDATA
MOV A,STACK
CLR C
SUBB A,#4
MOV R0,A
CALL OUT2H
MOV DPTR,#MBRK3
CALL PDATA
INC R0
CALL OUT2H
MOV DPTR,#MBRK4
CALL PDATA
INC R0
CALL OUT2H
MOV DPTR,#MBRK5
CALL PDATA
INC R0
CALL OUT2H
INC R0
CALL OUT2H
MOV DPTR,#MBRK6
CALL PDATA
MOV R0,#STACK
CALL OUT2H
JMP WARM
;*************************************************************
GO: CALL BYTES
JNC $+5
LJMP WARM
JNB F0,GXXXX
CJNE A,#CR,GO ;LOOK AGAIN IF SPACE
MOV HIBYTE,#HIGH(BYTENUM+1)
MOV LOBYTE,#LOW(BYTENUM+1)
MOV SP,STACK ;restore stack if necessary
POP DPL
POP DPH
POP B
POP PSW
POP ACC
GXXXX:
PUSH LOBYTE
PUSH HIBYTE
RET
;*************************************************************
HEXMATH:
CALL BADDR
JNC $+5
LJMP WARM
MOV FIRST,HIBYTE
MOV (FIRST+1),LOBYTE
CALL BADDR
JNC $+5
LJMP WARM
MOV A,(FIRST+1)
ADD A,LOBYTE
MOV (LAST+1),A ;STORE LOW BYTE OF SUM
MOV A,FIRST
ADDC A,HIBYTE
MOV LAST,A ;STORE HIGH BYTE OF SUM
MOV A,(FIRST+1)
CLR C
SUBB A,LOBYTE
MOV (TO+1),A ;STORE LOW BYTE OF DIFFERENCE
MOV A,FIRST
SUBB A,HIBYTE
MOV TO,A ;STORE HIGH BYTE OF DIFFERENCE
CALL CRLF
MOV R0,#FIRST ;POINT TO ADDEND
CALL OUT4HS
MOV A,#'+'
CALL OUTCH
CALL OUTS
MOV R0,#HIBYTE ;POINT TO AUGEND
CALL OUT4HS
MOV A,#'='
CALL OUTCH
CALL OUTS
MOV R0,#LAST ;POINT TO SUM
CALL OUT4HS
CALL CRLF
MOV R0,#FIRST ;POINT TO SUBTRAHEND
CALL OUT4HS
MOV A,#'-'
CALL OUTCH
CALL OUTS
MOV R0,#HIBYTE ;POINT TO MINUEND
CALL OUT4HS
MOV A,#'='
CALL OUTCH
CALL OUTS
MOV R0,#TO ;POINT TO DIFFERENCE
CALL OUT4HS
JMP WARM
;*************************************************************
JUMPTABL:
MOV DPTR,#MJUMP
CALL PDATA
JMP WARM
PAGE
;*************************************************************
;
;ROUTINE PDATA
; WRITES A MESSAGE TO THE TERMINAL
; ENTER WITH DPTR POINTING TO BEGINNING OF MESSAGE
; AND 04H AT END OF MESSAGE.
;
PDATA1: CALL OUTCH
INC DPTR
PDATA: CLR A
MOVC A,@A+DPTR
CJNE A,#EOT,PDATA1
RET
;*************************************************************
;
;ROUTINE IN
; READ AN 8-BIT CHAR FROM 8251A UART
;
IN: PUSH DPH
PUSH DPL
MOV DPTR,#UARTCONT
MOVX A,@DPTR
JNB ACC.1,$-1 ;WAIT FOR RX RDY
DEC DPL ;POINT TO DATA REGISTER
MOVX A,@DPTR
POP DPL
POP DPH
RET
;*************************************************************
;
;ROUTINE INCH
; READ A CHARACTER, ZERO HIGH BIT, & ECHO BACK TO TERMINAL
;
INCH: CALL IN ;READ 8-BIT CHAR.
ANL A,#7FH ;ZERO HIGH BIT
JMP OUT ;ECHO BACK
;*************************************************************
;
;ROUTINE OUTCH
; OUTPUT A CHARACTER
;
OUTCH: CALL OUT
JNC NOINPU ;TEST FOR INPUT DURING OUTPUT
CALL IN ;GET RID OF THE CHARACTER
JMP COOL ;RESET STACK POINTER
NOINPU: RET
;*************************************************************
;
;ROUTINE OUT
; SEND "A" REGISTER TO UART
; SET CARRY IF RX BUFFER IS FULL
;
OUT: PUSH DPH
PUSH DPL
PUSH ACC ;SAVE OUTPUT BYTE
MOV DPTR,#UARTCONT
MOVX A,@DPTR
JNB ACC.0,$-1 ;WAIT FOR TX EMPTY
MOV C,ACC.1 ;MOV RX RDY TO CARRY
DEC DPL ;POINT TO DATA REGISTER
POP ACC ;RESTORE OUTPUT BYTE
MOVX @DPTR,A ;AND OUTPUT IT
POP DPL
POP DPH
RET
PAGE 30
;*************************************************************
;
;ROUTINE INHEX
; READS 1 ASCII HEX CHAR, CONVERTS TO BINARY IN ACC. &
; STORES ORIGINAL CHAR IN B REG.
; CARRY SET IF NOT VALID HEX, CLEARED OTHERWISE.
;
INHEX: CALL INCH ;GET CHARACTER
MOV B,A ;STORE IN B
CJNE A,#CR,NOTCR ;IF <CR> SEND <LF> ALSO
MOV A,#LF
CALL OUTCH
NOTCR: MOV A,B ;RESTORE CHARACTER
JNB ACC.6,$+5 ;IF LOWER CASE
CLR ACC.5 ;CONVERT TO UPPER CASE
CLR C
SUBB A,#'0'
JC BAD ; ACC < '0'
SUBB A,#10
JNC $+7 ; ACC > '9'
ADD A,#10 ;RESTORE
LJMP GOOD ; '0' <= ACC <= '9'
ADD A,#('0'+10-'A'+10) ;CORRECT FOR (-'0'-10) & MAP 'A' INTO 10
JB ACC.7,BAD ; '9' < ACC < 'A'
CLR C
SUBB A,#16
JNC BAD ; ACC > 'F'
ADD A,#16
GOOD: CLR C
RET
BAD: SETB C
RET
;*************************************************************
;
;ROUTINE BYTES
; READ IN TWO BYTE HEX NUMBER TO HIBYTE,LOBYTE
; LAST CHARACTER READ RETURNED IN B REGISTER
;
; ERROR CODES: CARRY: F0:
; LEADING <CR> OR SPACE 0 1 (CHAR IN ACC)
; LEADING NONHEX CHARACTER 1 1 (CHAR IN ACC)
; OTHER NONHEX CHARACTER 1 0 (CHAR IN ACC)
;
BYTES: SETB F0 ;NO HEX READ YET
CLR A
MOV HIBYTE,A
MOV LOBYTE,A
MORE1: CALL INHEX
JNC OK1 ;JUMP IF HEX DIGIT
MOV A,B ;LOOK AT ASCII
CJNE A,#CR,$+6
LJMP CR1
CJNE A,#SPACE,BAD1
CR1: CLR C
RET
OK1: CLR F0
MOV R0,#LOBYTE ;POINTER
XCHD A,@R0 ;PUT 0 DIGIT IN LOW END OF LOBYTE
SWAP A ;ACC NOW HAS DIGIT 1 IN HIGH END
XCHD A,@R0 ;ACC NOW HAS DIGITS 1,0
XCH A,@R0 ;ACC HAS DIGITS 2,X;LOBYTE DONE.
DEC R0 ;POINT TO HIBYTE
XCHD A,@R0 ;ACC NOW HAS DIGITS 2,3
SWAP A ;ACC HAS DIGITS 3,2
XCH A,@R0 ;HIBYTE DONE
JMP MORE1 ;LOOK FOR ANOTHER DIGIT
BAD1: SETB C
RET
PAGE 19
;*************************************************************
;
;ROUTINE BUILD ADDRESS
; READ IN A 16-BIT HEX NUMBER TO HIBYTE,LOBYTE.
; RETURNS WITH CARRY & F0 SET IF A SECOND COMMAND CHARACTER
; IS FOUND. CHARACTER WILL BE IN ACCUMULATOR.
; RETURNS WITH CARRY SET AND F0 CLEAR IF NON-HEX.
;
BADDR: CALL BYTES
JNC ADDROK
JB F0,ADDRNOK ;SECOND COMMAND CHARACTER
JMP WARM ;ERROR
ADDROK: JB F0,BADDR ;LEADING SPACE OR CR
ADDRNOK:
RET
;*************************************************************
;
;ROUTINE BUILD ADDRESS #2
; READ IN A 16-BIT HEX NUMBER TO HIBYTE,LOBYTE.
; IGNORES LEADING SPACES. RETURNS WITH F0 SET IF
; A LEADING CARRIAGE RETURN IS FOUND.
;
BADDR2: CALL BYTES
JNC $+5
LJMP WARM ;NON-HEX
JNB F0,ADDROK2 ;NUMBER READ
CJNE A,#CR,BADDR2 ;IGNORE LEADING SPACE
ADDROK2:
RET
;*************************************************************
;
;ROUTINE OUTPUT SPACES
; OUTPUTS 1, 2, 3, OR 4 SPACES
;
OUT4S: CALL OUTS
OUT3S: CALL OUTS
OUT2S: CALL OUTS
OUTS: MOV A,#SPACE
JMP OUTCH
;*************************************************************
;
;ROUTINE OUTPUT CODE, TWO HEX, SPACE
; OUTPUTS PROGRAM MEMORY BYTE POINTED OUT BY DPTR
; AS TWO ASCII CHARACTERS FOLLOWED BY A SPACE.
; USES B REGISTER AS TEMP. STORE
;
OUTC2HS:
CLR A
MOVC A,@A+DPTR
MOV B,A ;TEMP STORE
CALL OUTHL
MOV A,B
CALL OUTHR
JMP OUTS
;*************************************************************
;
;ROUTINE MIDCHK
; INSERTS A SPACE IF LOW NYBBLE OF DPTR = 8.
; RETURNS WITH LOW NYBBLE IN ACC.
; DESTROYS B REGISTER.
;
MIDCHK: MOV A,DPL
ANL A,#0FH
XRL A,#08H
JNZ NOTMID
XCH A,B
CALL OUTS
XCH A,B
NOTMID: XRL A,#08H ;RESTORE A
RET
PAGE 14
;*************************************************************
;
;ROUTINES OUTPUT HEX LEFT
; OUTPUT HEX RIGHT
; CONVERTS A NYBBLE IN ACC. TO ASCII AND SENDS IT
;
OUTHL: SWAP A
OUTHR: ANL A,#0FH
JNB ACC.3,H2 ;<8
JB ACC.2,H1 ;>=C
JNB ACC.1,H2 ;<A
H1: ADD A,#07H
H2: ADD A,#('0') ;CONVERT TO ASCII
JMP OUTCH
PAGE 9
;*************************************************************
;
;ROUTINE OUTPUT TWO HEX
; OUTPUTS HEX CONTENTS OF LOCATION POINTED OUT BY R0
;
OUT2H: MOV A,@R0
CALL OUTHL
MOV A,@R0
JMP OUTHR
;*************************************************************
;
;ROUTINE CRLF
; SENDS A CARRIAGE RETURN AND A LINE FEED
;
CRLF: MOV A,#CR
CALL OUTCH
MOV A,#LF
JMP OUTCH
;*************************************************************
;
;ROUTINE DECREMENT 16
; DECREMENTS A 16-BIT NUMBER POINTED OUT BY R0.
; ENTER WITH LOW BYTE @R0 & HIGH BYTE @(R0-1).
; CARRY SET ON OVERFLOW, CLEARED OTHERWISE.
;
DEC16: CLR C
DEC @R0
MOV A,@R0
CPL A
JNZ DECEND
DEC R0
DEC @R0
MOV A,@R0
CPL A
JNZ DECEND
SETB C
DECEND: RET
PAGE 17
;*************************************************************
;
;ROUTINE INCREMENT 16
; INCREMENTS A 16-BIT NUMBER POINTED OUT BY R0.
; ENTER WITH LOW BYTE @R0 & HIGH BYTE @(R0-1).
; CARRY SET ON OVERFLOW, CLEARED OTHERWISE.
;
INC16: CLR C
INC @R0
MOV A,@R0
JNZ INCEND
DEC R0
INC @R0
MOV A,@R0
JNZ INCEND
SETB C
INCEND: RET
PAGE 20
;*************************************************************
;
;ROUTINE THREE ADRESSES
; GETS THREE 16-BIT HEX NUMBERS AND STORES THEM IN
; "FIRST", "LAST", AND "TO" RESPECTIVELY.
;
THRADR: CALL BADDR
JC THRERR
MOV FIRST,HIBYTE
MOV (FIRST+1),LOBYTE
CALL BADDR
JC THRERR
MOV LAST,HIBYTE
MOV (LAST+1),LOBYTE
CALL BADDR
JC THRERR
MOV TO,HIBYTE
MOV (TO+1),LOBYTE
RET
THRERR: JMP COOL
;*************************************************************
;
;ROUTINE COPY
; COPIES PROGRAM MEMORY LOCATED "FIRST" TO "LAST"
; TO RAM LOCATION STARTING AT "TO"
;
CPY: MOV DPH,FIRST
MOV DPL,(FIRST+1)
CLR A
MOVC A,@A+DPTR
MOV DPH,TO
MOV DPL,(TO+1)
MOVX @DPTR,A ;PUT DATA
MOV A,FIRST
CJNE A,LAST,CPY2
MOV A,(FIRST+1)
CJNE A,(LAST+1),CPY2
RET ;DONE
CPY2: MOV R0,#(FIRST+1)
CALL INC16
MOV R0,#(TO+1)
CALL INC16
JMP CPY
;*************************************************************
;
;ROUTINE OUT, 2 HEX, 3 SPACES
; OUTPUTS LOCATION POINTED OUT BY R0 FOLLOWED BY 3 SPACES
;
OUT2H3S:
CALL OUT2H
JMP OUT3S
PAGE 11
;*************************************************************
;
;ROUTINE OUTPUT R0
; OUTPUTS THE CONTENTS OF R0
; (8051 CAN'T ACCESS SFR'S INDIRECTLY--UGH)
;
OUTR0: MOV A,R0
CALL OUTHL
MOV A,R0
JMP OUTHR
PAGE 9
;*************************************************************
;
;ROUTINE OUTPUT R0, 3 SPACES
; OUTPUTS THE CONTENTS OF R0 AND THREE SPACES
;
OUTR03S:
CALL OUTR0
JMP OUT3S
;*************************************************************
;
;ROUTINE OUTPUT FOUR HEX, SPACE
;
; OUTPUTS TWO CONSECUTIVE INTERNAL MEMORY LOCATIONS,
; THE LOWER OF WHICH (HIGH BYTE OF NUMBER) IS POINTED
; OUT BY R0.
;
OUT4HS: CALL OUT2H
INC R0
CALL OUT2H
JMP OUTS
PAGE
;*************************************************************
FUNTAB: ;FUNCTION TABLE
DB 'A'
DW ALTER
DB 'B'
DW BREAK
DB 'C'
DW COPY
DB 'D'
DW DUMP
DB 'G'
DW GO
DB 'H'
DW HELP
DB 'I'
DW INSERT
DB 'J'
DW JUMPTABL
DB 'M'
DW MODIFY
DB 'V'
DW VERIFY
DB '#'
DW HEXMATH
DB 00H ;END OF TABLE
;*************************************************************
SFRTAB: ;SPECIAL FUNCTION REGISTER TABLE
DB 'P0 ',04H
MOV R0,P0
RET
CLR F0
RET
DB 'SP ',04H
MOV R0,SP
RET
CLR F0
RET
DB 'DPL ',04H
MOV R0,DPL
RET
MOV DPL,R0
RET
DB 'DPH ',04H
MOV R0,DPH
RET
MOV DPL,R0
RET
DB 'PCON',04H
MOV R0,PCON
RET
MOV PCON,R0
RET
DB 'TCON',04H
MOV R0,TCON
RET
MOV TCON,R0
RET
DB 'TMOD',04H
MOV R0,TMOD
RET
MOV TMOD,R0
RET
DB 'TL0 ',04H
MOV R0,TL0
RET
MOV TL0,R0
RET
DB 'TL1 ',04H
MOV R0,TL1
RET
MOV TL1,R0
RET
DB 'TH0 ',04H
MOV R0,TH0
RET
MOV TH0,R0
RET
DB 'TH1 ',04H
MOV R0,TH1
RET
MOV TH1,R0
RET
DB 'P1 ',04H
MOV R0,P1
RET
MOV P1,R0
RET
DB 'SCON',04H
MOV R0,SCON
RET
MOV SCON,R0
RET
DB 'SBUF',04H
MOV R0,SBUF
RET
MOV SBUF,R0
RET
DB 'P2 ',04H
MOV R0,P2
RET
CLR F0
RET
DB 'IE ',04H
MOV R0,IE
RET
MOV IE,R0
RET
DB 'P3 ',04H
MOV R0,P3
RET
MOV P3,R0
RET
DB 'IP ',04H
MOV R0,IP
RET
MOV IP,R0
RET
DB 'PSW ',04H
MOV R0,PSW
RET
MOV PSW,R0
RET
DB 'ACC ',04H
MOV R0,ACC
RET
MOV ACC,R0
RET
DB 'B ',04H
MOV R0,B
RET
MOV B,R0
RET
;*************************************************************
MPROMPT:
DB CR,LF,'UGH:',04H
MHELP: DB CR,LF,'REGISTER BANK 1 IS RESERVED'
DB CR,LF,'LAST 9 BYTES OF EXT. RAM USED BY BREAK ROUTINE'
DB CR,LF,'RAM @ 48H-50H IS USED BY MONITOR'
DB CR,LF,'RAM ABOVE 50H IS USED FOR STACK',LF
DB CR,LF,'COMMANDS ARE',LF
DB CR,LF,'A SSSS',TAB,TAB,TAB,'ALTER EXTERNAL MEMORY'
DB CR,LF,'AI SS',TAB,TAB,TAB,'ALTER INTERNAL MEMORY'
DB CR,LF,'B {AAAA {#}}',TAB,TAB,'BREAK @ AAAA (#=3,4,OR 5)
DB CR,LF,'C SSSS FFFF TTTT',TAB,'COPY BLOCK OF MEMORY'
DB CR,LF,'D SSSS {FFFF}',TAB,TAB,'DUMP PROGRAM MEMORY'
DB CR,LF,'DI SS {FF}',TAB,TAB,'DUMP INTERNAL MEMORY'
DB CR,LF,'G {AAAA}',TAB,TAB,'GO @ AAAA OR BREAKPOINT'
DB CR,LF,'H',TAB,TAB,TAB,'HELP'
DB CR,LF,'I SSSS FFFF HH',TAB,TAB,'INSERT "HH" INTO MEMORY'
DB CR,LF,'J', TAB, TAB,TAB, 'LIST JUMP TABLE'
DB CR,LF,'M SSSS',TAB,TAB,TAB,'MODIFY EXTERNAL MEMORY (ASCII)'
DB CR,LF,'V SSSS FFFF TTTT',TAB,'VERIFY MEMORY'
DB CR,LF,'# MMMM NNNN ',TAB,TAB,'HEX ADDITION & SUBTRACTION'
DB CR,LF,04H
MBRK1: DB CR,LF,'BREAK AT LOCATION ',04H
MBRK2: DB CR,LF,'ACC = ',04H
MBRK3: DB ' PSW = ',04H
MBRK4: DB ' B = ',04H
MBRK5: DB ' DPTR = ',04H
MBRK6: DB ' SP = ',04H
MINDEX: DB CR,LF,' 0 1 2 3 4 5 6 7 8 9 A B C D E F',04H
MNONO: DB CR,LF,'OOPS, THAT',27H,'S A NO-NO !',04H
MJUMP:
DB CR,LF, '0026 COOL',TAB, 'COOL START (RESET STACK POINTER)'
DB CR,LF, '0029 WARM',TAB, 'WARM START'
DB CR,LF, '002C IN',TAB, 'GET A BYTE FROM THE UART'
DB CR,LF, '002F INCH',TAB, 'GET A CHARACTER (ZERO PARITY)'
DB CR,LF, '0032 INHEX',TAB, 'GET A HEX CHAR (CARRY=NONHEX)'
DB CR,LF, '0035 BYTES',TAB, '2 BYTE HEX TO HI/LOBYTE'
DB CR,LF, '0038 BADDR',TAB, 'BUILD ADDRESS'
DB CR,LF, '003B THRADR',TAB, 'THREE ADDRESSES'
DB CR,LF, '003E OUT',TAB, 'OUTPUT BYTE IN ACC.'
DB CR,LF, '0041 OUTCH',TAB, 'OUTPUT CHARACTER IN ACC.'
DB CR,LF, '0044 OUTS',TAB, 'OUTPUT SPACE'
DB CR,LF, '0047 OUT2S',TAB, 'OUTPUT 2 SPACES'
DB CR,LF, '004A CRLF',TAB, 'OUTPUT [CR] AND [LF]'
DB CR,LF, '004D OUT2H',TAB, 'OUTPUT LOC. POINTED BY R0'
DB CR,LF, '0050 OUTR0',TAB, 'OUTPUT CONTENTS OF R0'
DB CR,LF, '0053 OUTC2HS',TAB, 'OUTPUT PROG. MEM. POINTED'
DB ' BY DPTR, AND SPACE'
DB CR,LF, '0056 PDATA',TAB, 'OUTPUT MESSAGE POINTED BY DPTR'
DB CR,LF, '0059 INC16',TAB, 'INCREMENT 2 BYTE NO.'
DB ' (R0=LOW BYTE)'
DB CR,LF, '005C DEC16',TAB, 'DECREMENT 2 BYTE NO.'
DB ' (R0+1=HIGH BYTE)'
DB CR,LF, '005F CPY',TAB, 'BLOCK COPY'
DB CR,LF, '0062 BRKPT',TAB, 'BREAKPOINT ROUTINE'
DB 04H
END